{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-05-04T14:58:20.803964Z",
     "start_time": "2025-05-04T14:58:20.628826Z"
    }
   },
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "def gradient_descent(X, y, learning_rate=0.01, num_iterations=1000):\n",
    "    m, n = X.shape\n",
    "    theta = np.zeros((n, 1))\n",
    "    cost_history = []\n",
    "\n",
    "    for iteration in range(num_iterations):\n",
    "        # 计算预测值\n",
    "        predictions = np.dot(X, theta)\n",
    "        # 计算误差\n",
    "        error = predictions - y\n",
    "        # 计算梯度\n",
    "        gradient = (1 / m) * np.dot(X.T, error)\n",
    "        # 更新参数\n",
    "        theta = theta - learning_rate * gradient\n",
    "\n",
    "        # 计算代价函数\n",
    "        cost = (1 / (2 * m)) * np.sum(np.square(error))\n",
    "        cost_history.append(cost)\n",
    "\n",
    "    return theta, cost_history\n",
    "\n",
    "\n",
    "# 生成一些示例数据\n",
    "np.random.seed(0)\n",
    "X = 2 * np.random.rand(100, 1)\n",
    "y = 4 + 3 * X + np.random.randn(100, 1)\n",
    "\n",
    "# 添加偏置项\n",
    "X_b = np.c_[np.ones((100, 1)), X]\n",
    "\n",
    "# 运行梯度下降\n",
    "theta, cost_history = gradient_descent(X_b, y, learning_rate=0.01, num_iterations=1000)\n",
    "\n",
    "# 打印最终参数\n",
    "print(\"最终参数 theta:\")\n",
    "print(theta)\n",
    "\n",
    "# 绘制代价函数随迭代次数的变化\n",
    "plt.plot(cost_history)\n",
    "plt.xlabel('迭代次数')\n",
    "plt.ylabel('代价函数值')\n",
    "plt.title('梯度下降过程中代价函数的变化')\n",
    "plt.show()"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最终参数 theta:\n",
      "[[4.04468715]\n",
      " [3.12593652]]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 20195 (\\N{CJK UNIFIED IDEOGRAPH-4EE3}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 20215 (\\N{CJK UNIFIED IDEOGRAPH-4EF7}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 20989 (\\N{CJK UNIFIED IDEOGRAPH-51FD}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 25968 (\\N{CJK UNIFIED IDEOGRAPH-6570}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 20540 (\\N{CJK UNIFIED IDEOGRAPH-503C}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 26799 (\\N{CJK UNIFIED IDEOGRAPH-68AF}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 24230 (\\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 19979 (\\N{CJK UNIFIED IDEOGRAPH-4E0B}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 38477 (\\N{CJK UNIFIED IDEOGRAPH-964D}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 36807 (\\N{CJK UNIFIED IDEOGRAPH-8FC7}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 31243 (\\N{CJK UNIFIED IDEOGRAPH-7A0B}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 20013 (\\N{CJK UNIFIED IDEOGRAPH-4E2D}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 30340 (\\N{CJK UNIFIED IDEOGRAPH-7684}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 21464 (\\N{CJK UNIFIED IDEOGRAPH-53D8}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 21270 (\\N{CJK UNIFIED IDEOGRAPH-5316}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 36845 (\\N{CJK UNIFIED IDEOGRAPH-8FED}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "C:\\Users\\30979\\AppData\\Roaming\\Python\\Python312\\site-packages\\IPython\\core\\pylabtools.py:170: UserWarning: Glyph 27425 (\\N{CJK UNIFIED IDEOGRAPH-6B21}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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CofDCofDuuGGG3Tw4MH0v4BByp544gmTl5dnHnroIfPuu++a2267zRQVFZmPP/7Ydmm+ccUVV5jly5ebd955x2zevNlceeWVZsSIEaapqSnR5r777jOhUMj84Q9/MFu3bjXXXnutKS8vN5FIJNHmlltuMcOGDTMrV640b731lpk2bZo5//zzTXt7u42vlbXWr19vvvCFL5jzzjvP3HbbbYnj9LE7Pv/8c1NVVWXmzp1r3njjDbNjxw7z0ksvmQ8//DDRhr5O349+9CMzZMgQ8+yzz5odO3aY3//+92bgwIHmgQceSLShn/vmueeeM/fcc4/5wx/+YCSZp59+Oum8W/06Y8YMU1NTY9auXWvWrl1rampqzFe/+tW06yfM9MHFF19sbrnllqRjo0ePNnfeeaelivyvvr7eSDKrV682xhgTi8VMWVmZue+++xJtWlpaTDgcNr/4xS+MMcYcPHjQ5OXlmSeeeCLR5tNPPzWBQMA8//zz3n6BLNbY2GhGjRplVq5caS699NJEmKGP3fP973/fTJky5bjn6Wt3XHnlleamm25KOjZ79mzzzW9+0xhDP7vl6DDjVr++++67RpJ5/fXXE23WrVtnJJm//vWvadXMNFOKWltbtXHjRk2fPj3p+PTp07V27VpLVflfQ0ODJGnw4MGSpB07dqiuri6pn4PBoC699NJEP2/cuFFtbW1JbSoqKlRTU8PPopt58+bpyiuv1Je//OWk4/Sxe5555hmNGzdO11xzjUpKSnThhRfqoYceSpynr90xZcoU/eUvf9EHH3wgSXr77bf12muv6Stf+Yok+jlT3OrXdevWKRwOa8KECYk2EydOVDgcTrvv+/2NJt22b98+dXR0qLS0NOl4aWmp6urqLFXlb8YYLVq0SFOmTFFNTY0kJfqyp37++OOPE23y8/N12mmnHdOGn0WnJ554Qm+99ZY2bNhwzDn62D0fffSRli1bpkWLFunuu+/W+vXr9Z3vfEfBYFA33ngjfe2S73//+2poaNDo0aOVk5Ojjo4O/fjHP9Z1110nib/TmeJWv9bV1amkpOSY9y8pKUm77wkzfeQ4TtJzY8wxx9A78+fP15YtW/Taa68dc64v/czPotPu3bt122236cUXX1RBQcFx29HH6YvFYho3bpyWLFkiSbrwwgu1bds2LVu2TDfeeGOiHX2dnieffFKPPvqoHnvsMZ177rnavHmzFi5cqIqKCs2ZMyfRjn7ODDf6taf2bvQ900wpGjp0qHJyco5JkfX19cekVpzcggUL9Mwzz+iVV17R8OHDE8fLysok6YT9XFZWptbWVh04cOC4bU5lGzduVH19vcaOHavc3Fzl5uZq9erV+tnPfqbc3NxEH9HH6SsvL9c555yTdOzss8/Wrl27JPH32S3f+973dOedd+rrX/+6xowZoxtuuEHf/e53VVtbK4l+zhS3+rWsrEx///vfj3n/zz77LO2+J8ykKD8/X2PHjtXKlSuTjq9cuVKTJ0+2VJX/GGM0f/58PfXUU3r55ZdVXV2ddL66ulplZWVJ/dza2qrVq1cn+nns2LHKy8tLarN371698847/Cwk/eM//qO2bt2qzZs3Jx7jxo3T9ddfr82bN2vkyJH0sUu++MUvHrO1wAcffKCqqipJ/H12y6FDhxQIJP/aysnJSVyaTT9nhlv9OmnSJDU0NGj9+vWJNm+88YYaGhrS7/u0lg+fouKXZv/617827777rlm4cKEpKioyO3futF2ab3z729824XDYrFq1yuzduzfxOHToUKLNfffdZ8LhsHnqqafM1q1bzXXXXdfjpYDDhw83L730knnrrbfMZZdddspfYnki3a9mMoY+dsv69etNbm6u+fGPf2y2b99ufve735kBAwaYRx99NNGGvk7fnDlzzLBhwxKXZj/11FNm6NCh5o477ki0oZ/7prGx0WzatMls2rTJSDL333+/2bRpU2LLEbf6dcaMGea8884z69atM+vWrTNjxozh0mybfv7zn5uqqiqTn59vLrroosQlxegdST0+li9fnmgTi8XMD3/4Q1NWVmaCwaC55JJLzNatW5Pe5/Dhw2b+/Plm8ODBprCw0Hz1q181u3bt8vjb+MfRYYY+ds9//dd/mZqaGhMMBs3o0aPNL3/5y6Tz9HX6IpGIue2228yIESNMQUGBGTlypLnnnntMNBpNtKGf++aVV17p8b/Jc+bMMca416/79+83119/vQmFQiYUCpnrr7/eHDhwIO36HWOMSW9sBwAAwB7WzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF/jrtkArFq7dq1uvfXWHs/NmDFDb775pvbt29fj+fXr1+sXv/iFfvOb3/R4/gc/+IHGjRunWbNm9Xj+vPPO0yOPPNKnugFkD8IMAKsikYhmzZqlxYsXJx3fuXOn7rzzTjU1NWnz5s3HvG7q1KmKxWLas2ePHnjgAU2dOjXp/MMPP6x9+/appaVFF1xwgR5++OFj3mPixInufREA1jDNBAAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI3bGQCwKhwO69lnn9Wzzz57zLkrrrhCBw8e1Lhx43p8bSAQ0PDhw3X77bf3eP7uu+9WYWGh3nnnnR7fY8yYMekVDyArOMYYY7sIAACAvmKaCQAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+Nr/B6vjZFe6gyGZAAAAAElFTkSuQmCC"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-04T14:58:21.247525Z",
     "start_time": "2025-05-04T14:58:21.075247Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "def gradient_descent(X, y, learning_rate=0.01, num_iterations=1000):\n",
    "    m, n = X.shape\n",
    "    theta = np.zeros((n, 1))\n",
    "    cost_history = []\n",
    "\n",
    "    for iteration in range(num_iterations):\n",
    "        # 计算预测值\n",
    "        predictions = np.dot(X, theta)\n",
    "        # 计算误差\n",
    "        error = predictions - y\n",
    "        # 计算梯度\n",
    "        gradient = (1 / m) * np.dot(X.T, error)\n",
    "        # 更新参数\n",
    "        theta = theta - learning_rate * gradient\n",
    "\n",
    "        # 计算代价函数\n",
    "        cost = (1 / (2 * m)) * np.sum(np.square(error))\n",
    "        cost_history.append(cost)\n",
    "\n",
    "    return theta, cost_history\n",
    "\n",
    "\n",
    "def predict(X, theta):\n",
    "    \"\"\"\n",
    "    此函数用于预测目标值。\n",
    "    :param X: 特征矩阵\n",
    "    :param theta: 模型参数\n",
    "    :return: 预测结果\n",
    "    \"\"\"\n",
    "    return np.dot(X, theta)\n",
    "\n",
    "\n",
    "def mean_squared_error(y_true, y_pred):\n",
    "    \"\"\"\n",
    "    此函数用于计算均方误差损失。\n",
    "    :param y_true: 真实的目标值\n",
    "    :param y_pred: 预测的目标值\n",
    "    :return: 均方误差损失\n",
    "    \"\"\"\n",
    "    m = len(y_true)\n",
    "    return (1 / (2 * m)) * np.sum(np.square(y_true - y_pred))\n",
    "\n",
    "\n",
    "# 生成一些示例数据\n",
    "np.random.seed(0)\n",
    "X = 2 * np.random.rand(100, 1)\n",
    "y = 4 + 3 * X + np.random.randn(100, 1)\n",
    "\n",
    "# 添加偏置项\n",
    "X_b = np.c_[np.ones((100, 1)), X]\n",
    "\n",
    "# 运行梯度下降\n",
    "theta, cost_history = gradient_descent(X_b, y, learning_rate=0.01, num_iterations=1000)\n",
    "\n",
    "# 打印最终参数\n",
    "print(\"最终参数 theta:\")\n",
    "print(theta)\n",
    "\n",
    "# 进行预测\n",
    "y_pred = predict(X_b, theta)\n",
    "\n",
    "# 计算损失\n",
    "loss = mean_squared_error(y, y_pred)\n",
    "print(\"均方误差损失:\", loss)\n",
    "\n",
    "# 绘制代价函数随迭代次数的变化\n",
    "plt.plot(cost_history)\n",
    "plt.xlabel('迭代次数')\n",
    "plt.ylabel('代价函数值')\n",
    "plt.title('梯度下降过程中代价函数的变化')\n",
    "plt.show()"
   ],
   "id": "2d8357db92c9e15",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最终参数 theta:\n",
      "[[4.04468715]\n",
      " [3.12593652]]\n",
      "均方误差损失: 0.5007493115640392\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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CofDCofDuuGGG3Tw4MH0v4BByp544gmTl5dnHnroIfPuu++a2267zRQVFZmPP/7Ydmm+ccUVV5jly5ebd955x2zevNlceeWVZsSIEaapqSnR5r777jOhUMj84Q9/MFu3bjXXXnutKS8vN5FIJNHmlltuMcOGDTMrV640b731lpk2bZo5//zzTXt7u42vlbXWr19vvvCFL5jzzjvP3HbbbYnj9LE7Pv/8c1NVVWXmzp1r3njjDbNjxw7z0ksvmQ8//DDRhr5O349+9CMzZMgQ8+yzz5odO3aY3//+92bgwIHmgQceSLShn/vmueeeM/fcc4/5wx/+YCSZp59+Oum8W/06Y8YMU1NTY9auXWvWrl1rampqzFe/+tW06yfM9MHFF19sbrnllqRjo0ePNnfeeaelivyvvr7eSDKrV682xhgTi8VMWVmZue+++xJtWlpaTDgcNr/4xS+MMcYcPHjQ5OXlmSeeeCLR5tNPPzWBQMA8//zz3n6BLNbY2GhGjRplVq5caS699NJEmKGP3fP973/fTJky5bjn6Wt3XHnlleamm25KOjZ79mzzzW9+0xhDP7vl6DDjVr++++67RpJ5/fXXE23WrVtnJJm//vWvadXMNFOKWltbtXHjRk2fPj3p+PTp07V27VpLVflfQ0ODJGnw4MGSpB07dqiuri6pn4PBoC699NJEP2/cuFFtbW1JbSoqKlRTU8PPopt58+bpyiuv1Je//OWk4/Sxe5555hmNGzdO11xzjUpKSnThhRfqoYceSpynr90xZcoU/eUvf9EHH3wgSXr77bf12muv6Stf+Yok+jlT3OrXdevWKRwOa8KECYk2EydOVDgcTrvv+/2NJt22b98+dXR0qLS0NOl4aWmp6urqLFXlb8YYLVq0SFOmTFFNTY0kJfqyp37++OOPE23y8/N12mmnHdOGn0WnJ554Qm+99ZY2bNhwzDn62D0fffSRli1bpkWLFunuu+/W+vXr9Z3vfEfBYFA33ngjfe2S73//+2poaNDo0aOVk5Ojjo4O/fjHP9Z1110nib/TmeJWv9bV1amkpOSY9y8pKUm77wkzfeQ4TtJzY8wxx9A78+fP15YtW/Taa68dc64v/czPotPu3bt122236cUXX1RBQcFx29HH6YvFYho3bpyWLFkiSbrwwgu1bds2LVu2TDfeeGOiHX2dnieffFKPPvqoHnvsMZ177rnavHmzFi5cqIqKCs2ZMyfRjn7ODDf6taf2bvQ900wpGjp0qHJyco5JkfX19cekVpzcggUL9Mwzz+iVV17R8OHDE8fLysok6YT9XFZWptbWVh04cOC4bU5lGzduVH19vcaOHavc3Fzl5uZq9erV+tnPfqbc3NxEH9HH6SsvL9c555yTdOzss8/Wrl27JPH32S3f+973dOedd+rrX/+6xowZoxtuuEHf/e53VVtbK4l+zhS3+rWsrEx///vfj3n/zz77LO2+J8ykKD8/X2PHjtXKlSuTjq9cuVKTJ0+2VJX/GGM0f/58PfXUU3r55ZdVXV2ddL66ulplZWVJ/dza2qrVq1cn+nns2LHKy8tLarN371698847/Cwk/eM//qO2bt2qzZs3Jx7jxo3T9ddfr82bN2vkyJH0sUu++MUvHrO1wAcffKCqqipJ/H12y6FDhxQIJP/aysnJSVyaTT9nhlv9OmnSJDU0NGj9+vWJNm+88YYaGhrS7/u0lg+fouKXZv/617827777rlm4cKEpKioyO3futF2ab3z729824XDYrFq1yuzduzfxOHToUKLNfffdZ8LhsHnqqafM1q1bzXXXXdfjpYDDhw83L730knnrrbfMZZdddspfYnki3a9mMoY+dsv69etNbm6u+fGPf2y2b99ufve735kBAwaYRx99NNGGvk7fnDlzzLBhwxKXZj/11FNm6NCh5o477ki0oZ/7prGx0WzatMls2rTJSDL333+/2bRpU2LLEbf6dcaMGea8884z69atM+vWrTNjxozh0mybfv7zn5uqqiqTn59vLrroosQlxegdST0+li9fnmgTi8XMD3/4Q1NWVmaCwaC55JJLzNatW5Pe5/Dhw2b+/Plm8ODBprCw0Hz1q181u3bt8vjb+MfRYYY+ds9//dd/mZqaGhMMBs3o0aPNL3/5y6Tz9HX6IpGIue2228yIESNMQUGBGTlypLnnnntMNBpNtKGf++aVV17p8b/Jc+bMMca416/79+83119/vQmFQiYUCpnrr7/eHDhwIO36HWOMSW9sBwAAwB7WzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF8jzAAAAF/jrtkArFq7dq1uvfXWHs/NmDFDb775pvbt29fj+fXr1+sXv/iFfvOb3/R4/gc/+IHGjRunWbNm9Xj+vPPO0yOPPNKnugFkD8IMAKsikYhmzZqlxYsXJx3fuXOn7rzzTjU1NWnz5s3HvG7q1KmKxWLas2ePHnjgAU2dOjXp/MMPP6x9+/appaVFF1xwgR5++OFj3mPixInufREA1jDNBAAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI0wAwAAfI3bGQCwKhwO69lnn9Wzzz57zLkrrrhCBw8e1Lhx43p8bSAQ0PDhw3X77bf3eP7uu+9WYWGh3nnnnR7fY8yYMekVDyArOMYYY7sIAACAvmKaCQAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+BphBgAA+Nr/B6vjZFe6gyGZAAAAAElFTkSuQmCC"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-04T14:58:21.513835Z",
     "start_time": "2025-05-04T14:58:21.319112Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "def gradient_descent(X, y, learning_rate=0.01, num_iterations=1000):\n",
    "    m, n = X.shape\n",
    "    theta = np.zeros((n, 1))\n",
    "    cost_history = []\n",
    "\n",
    "    for iteration in range(num_iterations):\n",
    "        # 计算预测值\n",
    "        predictions = np.dot(X, theta)\n",
    "        # 计算误差\n",
    "        error = predictions - y\n",
    "        # 计算梯度\n",
    "        gradient = (1 / m) * np.dot(X.T, error)\n",
    "        # 更新参数\n",
    "        theta = theta - learning_rate * gradient\n",
    "\n",
    "        # 计算代价函数\n",
    "        cost = (1 / (2 * m)) * np.sum(np.square(error))\n",
    "        cost_history.append(cost)\n",
    "\n",
    "    return theta, cost_history\n",
    "\n",
    "\n",
    "def predict(X, theta):\n",
    "    \"\"\"\n",
    "    此函数用于预测目标值。\n",
    "    :param X: 特征矩阵\n",
    "    :param theta: 模型参数\n",
    "    :return: 预测结果\n",
    "    \"\"\"\n",
    "    return np.dot(X, theta)\n",
    "\n",
    "def mean_squared_error(y_true, y_pred):\n",
    "    \"\"\"\n",
    "    此函数用于计算均方误差损失。\n",
    "    :param y_true: 真实的目标值\n",
    "    :param y_pred: 预测的目标值\n",
    "    :return: 均方误差损失\n",
    "    \"\"\"\n",
    "    m = len(y_true)\n",
    "    return (1 / (2 * m)) * np.sum(np.square(y_true - y_pred))\n",
    "\n",
    "\n",
    "# 定义数据生成函数\n",
    "def generate_data(num_samples, num_features, true_theta, noise_std=0.1):\n",
    "    \"\"\"\n",
    "    生成线性回归所需的数据。\n",
    "    :param num_samples: 样本数量\n",
    "    :param num_features: 特征数量\n",
    "    :param true_theta: 真实的参数值\n",
    "    :param noise_std: 噪声的标准差\n",
    "    :return: 特征矩阵 X 和标签向量 y\n",
    "    \"\"\"\n",
    "    X = np.random.randn(num_samples, num_features)\n",
    "    # 添加偏置项对应的全 1 列\n",
    "    X_b = np.c_[np.ones((num_samples, 1)), X]\n",
    "    # 生成无噪声的真实标签\n",
    "    y_true = np.dot(X_b, true_theta)\n",
    "    # 添加高斯噪声\n",
    "    y = y_true + np.random.normal(0, noise_std, (num_samples, 1))\n",
    "    return X_b, y\n",
    "\n",
    "\n",
    "# 定义真实的参数值\n",
    "true_theta = np.array([[4], [3]])\n",
    "\n",
    "# 生成数据\n",
    "num_samples = 100\n",
    "num_features = 1\n",
    "X_b, y = generate_data(num_samples, num_features, true_theta)\n",
    "\n",
    "# 运行梯度下降\n",
    "theta, cost_history = gradient_descent(X_b, y, learning_rate=0.01, num_iterations=1000)\n",
    "\n",
    "# 打印最终参数\n",
    "print(\"最终参数 theta:\")\n",
    "print(theta)\n",
    "\n",
    "# 进行预测\n",
    "y_pred = predict(X_b, theta)\n",
    "\n",
    "# 计算损失\n",
    "loss = mean_squared_error(y, y_pred)\n",
    "print(\"均方误差损失:\", loss)\n",
    "\n",
    "# 绘制代价函数随迭代次数的变化\n",
    "plt.plot(cost_history)\n",
    "plt.xlabel('迭代次数')\n",
    "plt.ylabel('代价函数值')\n",
    "plt.title('梯度下降过程中代价函数的变化')\n",
    "plt.show()"
   ],
   "id": "2ca06f2d8e924104",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最终参数 theta:\n",
      "[[3.99296802]\n",
      " [3.00966728]]\n",
      "均方误差损失: 0.004009584814451088\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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TYjb7Zbb7Y5HeQAAIAEk9H7RlJQUTZw4UcuWLetyfdmyZZo8ebJFVQEAgESS0CMzkjR37lzdcccdqqio0KWXXqolS5Zo3759uueee6wuDQAAJICEDzO33HKLjh49qgULFujQoUMqLy/Xm2++qeHDh1tdGgAASAAJf85MX3HODAAA9hPJz++EXjMDAABwNoQZAABga4QZAABga4QZAABga4QZAABga4QZAABga4QZAABga4QZAABga4QZAABgawn/OIO+Ch1w7PP5LK4EAAD0VOjndk8eVNDvw0x9fb0kqaSkxOJKAABApOrr6+XxeM7Ypt8/mykYDOrgwYPKzMyUw+GI6nf7fD6VlJRo//79PPcphujn+KCf44N+jh/6Oj5i1c/GGNXX16uoqEhO55lXxfT7kRmn06ni4uKY/h5ZWVn8DyUO6Of4oJ/jg36OH/o6PmLRz2cbkQlhATAAALA1wgwAALA1wkwfuN1u/eQnP5Hb7ba6lH6Nfo4P+jk+6Of4oa/jIxH6ud8vAAYAAP0bIzMAAMDWCDMAAMDWCDMAAMDWCDMAAMDWCDO99NRTT6msrEypqamaOHGiPvzwQ6tLspXKykpNmjRJmZmZys/P14wZM7R9+/YubYwxmj9/voqKipSWlqapU6dq69atXdr4/X7df//9ysvLU0ZGhr75zW/qwIED8fyj2EZlZaUcDofmzJkTvkYfR09VVZVuv/125ebmKj09XRMmTND69evD9+nrvmtvb9ejjz6qsrIypaWlaeTIkVqwYIGCwWC4Df3cOx988IFuvPFGFRUVyeFw6LXXXutyP1r9evz4cd1xxx3yeDzyeDy64447VFdX1/c/gEHEXnrpJZOcnGyeeeYZs23bNjN79myTkZFh9u7da3VptnHttdeaZ5991mzZssVs2rTJTJ8+3ZSWlpqGhoZwm8cff9xkZmaaV155xWzevNnccsstZujQocbn84Xb3HPPPWbYsGFm2bJlZsOGDeZrX/uaOf/88017e7sVf6yEtWbNGjNixAgzfvx4M3v27PB1+jg6jh07ZoYPH27uuusus3r1arN7927z9ttvm507d4bb0Nd99/Of/9zk5uaaN954w+zevdv88Y9/NIMGDTKLFi0Kt6Gfe+fNN980jzzyiHnllVeMJPOnP/2py/1o9eu0adNMeXm5WblypVm5cqUpLy83N9xwQ5/rJ8z0wkUXXWTuueeeLtdGjx5tHn74YYsqsr+amhojySxfvtwYY0wwGDSFhYXm8ccfD7dpaWkxHo/HPP3008YYY+rq6kxycrJ56aWXwm2qqqqM0+k0//3f/x3fP0ACq6+vN6NGjTLLli0zV155ZTjM0MfR89BDD5kpU6ac9j59HR3Tp083d999d5drN910k7n99tuNMfRztHw5zESrX7dt22YkmY8++ijcZtWqVUaS+eyzz/pUM9NMEWptbdX69et1zTXXdLl+zTXXaOXKlRZVZX9er1eSlJOTI0navXu3qquru/Sz2+3WlVdeGe7n9evXq62trUuboqIilZeX83dxkvvuu0/Tp0/X1Vdf3eU6fRw9r7/+uioqKnTzzTcrPz9fF1xwgZ555pnwffo6OqZMmaJ33nlHO3bskCR9/PHHWrFiha6//npJ9HOsRKtfV61aJY/Ho4svvjjc5pJLLpHH4+lz3/f7B01GW21trQKBgAoKCrpcLygoUHV1tUVV2ZsxRnPnztWUKVNUXl4uSeG+7K6f9+7dG26TkpKiwYMHn9KGv4sOL730kjZs2KC1a9eeco8+jp5du3Zp8eLFmjt3rn784x9rzZo1euCBB+R2u3XnnXfS11Hy0EMPyev1avTo0UpKSlIgENBjjz2mW2+9VRL/pmMlWv1aXV2t/Pz8U74/Pz+/z31PmOklh8PR5b0x5pRr6JlZs2bpk08+0YoVK06515t+5u+iw/79+zV79mz99a9/VWpq6mnb0cd9FwwGVVFRoYULF0qSLrjgAm3dulWLFy/WnXfeGW5HX/fNyy+/rKVLl+rFF1/U2LFjtWnTJs2ZM0dFRUWaOXNmuB39HBvR6Nfu2kej75lmilBeXp6SkpJOSZE1NTWnpFac3f3336/XX39d7733noqLi8PXCwsLJemM/VxYWKjW1lYdP378tG0GsvXr16umpkYTJ06Uy+WSy+XS8uXL9atf/UoulyvcR/Rx3w0dOlTnnXdel2tjxozRvn37JPHvOVp+9KMf6eGHH9Z3vvMdjRs3TnfccYd++MMfqrKyUhL9HCvR6tfCwkIdPnz4lO8/cuRIn/ueMBOhlJQUTZw4UcuWLetyfdmyZZo8ebJFVdmPMUazZs3Sq6++qnfffVdlZWVd7peVlamwsLBLP7e2tmr58uXhfp44caKSk5O7tDl06JC2bNnC34Wkq666Sps3b9amTZvCr4qKCt12223atGmTRo4cSR9HyWWXXXbK0QI7duzQ8OHDJfHvOVqamprkdHb9sZWUlBTemk0/x0a0+vXSSy+V1+vVmjVrwm1Wr14tr9fb977v0/LhASq0Nfu3v/2t2bZtm5kzZ47JyMgwe/bssbo02/jBD35gPB6Pef/9982hQ4fCr6ampnCbxx9/3Hg8HvPqq6+azZs3m1tvvbXbrYDFxcXm7bffNhs2bDBf//rXB/wWyzM5eTeTMfRxtKxZs8a4XC7z2GOPmc8//9z8/ve/N+np6Wbp0qXhNvR1382cOdMMGzYsvDX71VdfNXl5eebBBx8Mt6Gfe6e+vt5s3LjRbNy40UgyTzzxhNm4cWP4yJFo9eu0adPM+PHjzapVq8yqVavMuHHj2JptpX/7t38zw4cPNykpKebCCy8MbylGz0jq9vXss8+G2wSDQfOTn/zEFBYWGrfbba644gqzefPmLt/T3NxsZs2aZXJyckxaWpq54YYbzL59++L8p7GPL4cZ+jh6/vznP5vy8nLjdrvN6NGjzZIlS7rcp6/7zufzmdmzZ5vS0lKTmppqRo4caR555BHj9/vDbejn3nnvvfe6/f/kmTNnGmOi169Hjx41t912m8nMzDSZmZnmtttuM8ePH+9z/Q5jjOnb2A4AAIB1WDMDAABsjTADAABsjTADAABsjTADAABsjTADAABsjTADAABsjTADAABsjTADAABsjadmA7DUypUrde+993Z7b9q0aVq3bp1qa2u7vb9mzRo9/fTT+t3vftft/UcffVQVFRWaMWNGt/fHjx+vF154oVd1A0gchBkAlvL5fJoxY4bmz5/f5fqePXv08MMPq6GhQZs2bTrlc1OnTlUwGNTBgwe1aNEiTZ06tcv95557TrW1tWppadGECRP03HPPnfIdl1xySfT+IAAswzQTAACwNcIMAACwNcIMAACwNcIMAACwNcIMAACwNcIMAACwNcIMAACwNcIMAACwNcIMAACwNcIMAACwNR5nAMBSHo9Hb7zxht54441T7l177bWqq6tTRUVFt591Op0qLi7W3//933d7/8c//rHS0tK0ZcuWbr9j3LhxfSseQEJwGGOM1UUAAAD0FtNMAADA1ggzAADA1ggzAADA1ggzAADA1ggzAADA1ggzAADA1ggzAADA1ggzAADA1ggzAADA1v4/O+YfPz6hBqMAAAAASUVORK5CYII="
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-04T14:58:21.782792Z",
     "start_time": "2025-05-04T14:58:21.780283Z"
    }
   },
   "cell_type": "code",
   "source": "",
   "id": "c4ea1d0552758909",
   "outputs": [],
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
